package com.ssm.changeunit.command;

import com.ssm.changeunit.Branch;
import com.ssm.changeunit.BranchFactory;
import com.ssm.changeunit.ChangeUnit;
import com.ssm.changeunit.ChangeUnitItem;
import com.ssm.changeunit.CreateException;
import com.ssm.changeunit.Environment;
import com.ssm.changeunit.communicate.*;
import com.ssm.changeunit.persistance.*;
import com.ssm.changeunit.util.FileUtil;
import com.ssm.changeunit.util.ZipUtil;
import java.io.IOException;
import org.apache.log4j.Logger;

/**
 * 
 * @author 시리우스
 */
public class CloneCommandWorker extends CommandWorker {
    private Logger log = Logger.getLogger(CloneCommandWorker.class);

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,id=DCE.FB262655-3F9B-225C-A27B-0A5DABCA5707]
    // </editor-fold> 
    public CloneCommandWorker () {
    }

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,id=DCE.6BB5A532-04B4-03C7-F021-CB7CC3457740]
    // </editor-fold> 
    public void work (CommandWorkerOptions commandWorkerOptions) throws CommandWorkerException {
        if( commandWorkerOptions == null )
            throw new CommandWorkerException("Option이 null입니다.");
        
        if( !commandWorkerOptions.hasCommandWorkerOption("server") )
            throw new CommandWorkerException("server Option이 존재하지 않습니다.");
        
        // Item option을 꺼내옵니다.
        CommandWorkerOption serverCommandWorkerOption = commandWorkerOptions.getCommandWorkerOption("server");
        
        // Item option에 해당하는 item들을 가져옵니다.
        String[] servers = serverCommandWorkerOption.getValues();
        
        // item의 값이 없는 경우
        if( servers.length == 0 )
            throw new CommandWorkerException("Server의 값이 존재하지 않습니다.");
        
        // 데이터베이스 체크
        log.debug("데이터베이스가 존재하는지 검사합니다.");
        
        try {
            if(DatabaseManager.getInstance().isExists())
                throw new CommandWorkerException("이미 데이터베이스가 존재합니다.");
        }
        catch(PersistanceException ex) {
            throw new CommandWorkerException(ex);
        }
        
        log.info("디렉토리 초기화..");
        
        // 디렉토리 생성
        FileUtil.directoryCreateOrNone(".changeunit");
        
        log.info("프로퍼티 초기화..");
        try {
            // 현재 Branch 프로퍼티를 master로 초기화
            Environment.setCurrentBranch("master");
        } 
        catch (IOException ex) {
            throw new CommandWorkerException("프로퍼티 초기화 실패");
        }
        
        // 서버에 다운로드 요청
        ChangeUnitClient client = new ChangeUnitClient(servers[0]);
        
        // 파일에 기록
        try {
            FileUtil.saveByteDataToFile(Environment.ROOT_DIR + "db.zip", client.getDatabase());
            
            ZipUtil.unZipFile(Environment.ROOT_DIR + "db.zip", Environment.DATABASE_NAME, true);
        }
        catch(Exception ex) {
            throw new CommandWorkerException("데이터베이스를 파일에 기록할 수 없습니다.", ex);
        }
        finally {
            if(FileUtil.hasFile(Environment.ROOT_DIR + "db.zip"))
                FileUtil.delete(Environment.ROOT_DIR + "db.zip");
        }
        
        try {
            Branch currentBranch = new BranchFactory().createProduct(Environment.getCurrentBranch());

            // 타겟 Branch의 ChangeUnitItem을 가져와 생성
            ChangeUnit ChangeUnit = currentBranch.getCurrentChangeUnit();

            ManagedItemListDAO managedItemListDAO = new ManagedItemListDAO();

            for(ManagedItemListDTO managedItemListDTO : managedItemListDAO.list()) {
                managedItemListDAO.delete(managedItemListDTO.getFilePath());
            }

            // 생성
            for(ChangeUnitItem changeUnitItem: ChangeUnit.getChangeUnitItems()) {
                ManagedItemListDTO managedItemListDTO = new ManagedItemListDTO();
                managedItemListDTO.setFilePath(changeUnitItem.getFilePath());
                managedItemListDAO.insert(managedItemListDTO);

                FileUtil.saveDataToFile(Environment.ROOT_DIR + changeUnitItem.getFilePath(), new String(changeUnitItem.getRefChangeLog().getContent()));
            }
        }
        catch(IOException ex) {
            throw new CommandWorkerException(ex);
        }
        catch(CreateException ex) {
            throw new CommandWorkerException(ex);
        }
        catch(PersistanceException ex) {
            throw new CommandWorkerException(ex);
        }
    }
}

